/* PexifTool - $Revision$
 * Copyright (C) 2011 Petros Dolaschjan.  All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
 *  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *	$Id$
 */
package de.pd.pjim2.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;

import de.pd.pjim2.bean.PJFolderChangesBean;
import de.pd.pjim2.bean.PJImageFile;
import de.pd.pjim2.bean.PJImageSearchResult;
import de.pd.pjim2.bean.PJParameters;
import de.pd.pjim2.event.ImageProcessEvent;
import de.pd.pjim2.log.ConsoleLogger;

/** The controller for the commandline.
 * @author petros
 *
 */
public class PJConsoleController implements ImageProcessEvent {

	private static Options options = null; // Command line options
	
	private final static String OPTION_PREVIEW = "p";
	private final static String OPTION_RENAME = "r";
	private final static String OPTION_MOVE = "m";
	private final static String OPTION_SUBDIRS = "s";
	private final static String OPTION_SRC_DIR = "d";
	private final static String OPTION_DATE_TIME_OFFSET = "t";
	private final static String OPTION_ROTATE = "o";
	private final static String OPTION_WINDOW_MODE = "w";

	private CommandLine mCommandLine;
	
	static {
		options = new Options();
		options.addOption(OPTION_PREVIEW, false, "Preview only (makes no changes)");
		options.addOption(OPTION_RENAME, false, "Rename images");
		options.addOption(OPTION_MOVE, false, "Move images into directories");
		options.addOption(OPTION_SUBDIRS, false, "Scan subfolders");
		options.addOption(OPTION_ROTATE, false, "Auto-Rotate images (based on exif info)");
		options.addOption(OPTION_SRC_DIR, true, "The source directory");
		options.addOption(OPTION_WINDOW_MODE, false, "Opens the GUI version of PJImageManager2");
		options.addOption(OPTION_DATE_TIME_OFFSET, true, "The time offset for the hours (e.g. +3 if the camera time was 3 hours behind)");
	}
	
	
	
	/** Runs the application.
	 * @param args The command line args.
	 */
	public void run(String[] args) {
		PJParameters params = getParams(args);
		
		// check if window mode is activated
		// if so, then switch to the GUI app
		if(params.isWindowMode()) {
			System.out.println("Running in window mode");
			PJWindowController wc = new PJWindowController();
			wc.run(args);
			return;
		}
		
		PJImageController imgCtr = new PJImageController(new ConsoleLogger(), this);
		
		// 1. prepare
		PJImageSearchResult searchResult = null;
		try {
			searchResult = imgCtr.prepare(params);
		} catch (PJImageControllerException ex) {
			switch (ex.getExType()) {
			case DIR_NOT_FOUND:
				System.out.println("Folder " + params.getSrcDir() + " does not exist!");
				break;

			default:
				break;
			}
		}
		if(searchResult == null || searchResult.getTotal() == 0) {
			System.exit(0);
		}
		
		// 2. show the preview
		imgCtr.printPreview(searchResult);
		
		// 3. check user input
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		System.out.println("Procceed? (y/n)");
		try {
			String answer = br.readLine();
			if(!answer.equalsIgnoreCase("y")) {
				System.out.println("Abborting");
				System.exit(0);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// 4. process
		imgCtr.proccess(searchResult);
	}
	
	/** Read the args and create a params object.
	 * @param args
	 * @return
	 */
	private PJParameters getParams(String[] args) {
		PJParameters params = new PJParameters();
		
		CommandLineParser clp = new PosixParser();
		try {
			mCommandLine = clp.parse(options, args);
		} catch (ParseException e) {
			System.err.println(e.getMessage());
			System.exit(1);
		}
		
		// the src dir is necessary
		if(!mCommandLine.hasOption(OPTION_SRC_DIR) && !mCommandLine.hasOption(OPTION_WINDOW_MODE)) {
			printHelp();
			System.exit(1);
		}
		if(mCommandLine.hasOption(OPTION_DATE_TIME_OFFSET)) {
			int offset = 0;
			try {
				offset = Integer.parseInt(mCommandLine.getOptionValue(OPTION_DATE_TIME_OFFSET));
				System.out.println("Offset " + offset);
			} catch(NumberFormatException ne) {
				System.err.println("Could not parse the offset. Please enter a valid integer");
			}
			params.setDateTimeOffset(offset);
		}
		
		params.setSrcDir(mCommandLine.getOptionValue(OPTION_SRC_DIR));
		params.setMoveImages(mCommandLine.hasOption(OPTION_MOVE));
		params.setRenameImages(mCommandLine.hasOption(OPTION_RENAME));
		params.setPreviewOnly(mCommandLine.hasOption(OPTION_PREVIEW));
		params.setScanSubfolders(mCommandLine.hasOption(OPTION_SUBDIRS));
		params.setRotateImages(mCommandLine.hasOption(OPTION_ROTATE));
		params.setWindowMode(mCommandLine.hasOption(OPTION_WINDOW_MODE));
		
		return params;
	}
	
	public void printHelp() {
		HelpFormatter help = new HelpFormatter();
		help.printHelp("pjim2.sh", options);
	}

	/* (non-Javadoc)
	 * @see de.pd.pjim2.event.ImageProcessEvent#didFinishScanning()
	 */
	@Override
	public void didFinishScanning() {
		System.out.println("Finished scanning");
	}

	/* (non-Javadoc)
	 * @see de.pd.pjim2.event.ImageProcessEvent#didFinishProcessing()
	 */
	@Override
	public void didFinishProcessing() {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see de.pd.pjim2.event.ImageProcessEvent#didScanFolder(java.lang.String)
	 */
	@Override
	public void didScanFolder(PJFolderChangesBean pChangesBean) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see de.pd.pjim2.event.ImageProcessEvent#didScanImage(de.pd.pjim2.bean.PJImageFile)
	 */
	@Override
	public void didScanImage(PJImageFile pImageFile) {
		// TODO Auto-generated method stub
		System.out.println("Scaning: " + pImageFile.getSrcFile().getName());
	}

	/* (non-Javadoc)
	 * @see de.pd.pjim2.event.ImageProcessEvent#didStartProcessingFolder(de.pd.pjim2.bean.PJFolderChangesBean)
	 */
	@Override
	public void didStartProcessingFolder(PJFolderChangesBean pFolder) {
		// TODO Auto-generated method stub
		
	}

	/* (non-Javadoc)
	 * @see de.pd.pjim2.event.ImageProcessEvent#didProcessImage(de.pd.pjim2.bean.PJImageFile)
	 */
	@Override
	public void didProcessImage(String pImage) {
		// TODO Auto-generated method stub
		
	}
	
}
